using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Windows.Forms;
using Microsoft.Win32;

namespace WIT.DAQ.Core.Helper;

/// <summary>
/// Winform帮助类
/// </summary>
internal class WinformHelper
{
	/// <summary>
	/// 开机启动的注册表父级路径
	/// </summary>
	internal static readonly RegistryKey REGISTRY_PARENT_KEY = Registry.LocalMachine;

	/// <summary>
	/// 开机启动的注册表子路径
	/// </summary>
	internal const string REGISTRY_PATH = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

	/// <summary>
	/// 判断程序是否以管理员身份运行
	/// </summary>
	/// <returns></returns>
	internal static bool IsAdministrator()
	{
		WindowsIdentity current = WindowsIdentity.GetCurrent();
		WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);
		return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
	}

	/// <summary>
	/// 判断某个程序是否已设置开机启动
	/// </summary>
	/// <param name="applicationName">开机启动的程序名</param>  
	/// <returns></returns>
	internal static bool IsAutoRun(string applicationName)
	{
		bool result = false;
		RegistryKey registryKey = REGISTRY_PARENT_KEY.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
		try
		{
			string[] valueNames = registryKey.GetValueNames();
			foreach (string text in valueNames)
			{
				if (text == applicationName)
				{
					result = true;
					break;
				}
			}
		}
		catch (Exception ex)
		{
			MethodBase currentMethod = MethodBase.GetCurrentMethod();
			throw new Exception(currentMethod.DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
		return result;
	}

	/// <summary>
	/// 判断某个程序是否已设置开机启动
	/// </summary>
	/// <param name="applicationName">开机启动的程序名</param> 
	/// <param name="parentKey">注册表父级路径 （例：Registry.LocalMachine/Registry.CurrentUser）</param> 
	/// <param name="path">注册表子路径 （例：@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"）</param> 
	/// <returns></returns>
	internal static bool IsAutoRun(string applicationName, RegistryKey parentKey, string path)
	{
		bool result = false;
		RegistryKey registryKey = parentKey.CreateSubKey(path);
		try
		{
			string[] valueNames = registryKey.GetValueNames();
			foreach (string text in valueNames)
			{
				if (text == applicationName)
				{
					result = true;
					break;
				}
			}
		}
		catch (Exception ex)
		{
			MethodBase currentMethod = MethodBase.GetCurrentMethod();
			throw new Exception(currentMethod.DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
		return result;
	}

	/// <summary>  
	/// 设置程序开机启动（修改程序在注册表中的键值  ）
	/// </summary>  
	/// <param name="isAutoRun">true:开机启动,false:不开机自启</param> 
	/// <param name="applicationName">开机启动的程序名</param> 
	internal static void AutoRun(bool isAutoRun, string applicationName)
	{
		RegistryKey registryKey = REGISTRY_PARENT_KEY.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
		try
		{
			if (isAutoRun)
			{
				registryKey.SetValue(applicationName, Application.ExecutablePath);
			}
			else
			{
				registryKey.DeleteValue(applicationName, throwOnMissingValue: false);
			}
		}
		catch (Exception ex)
		{
			MethodBase currentMethod = MethodBase.GetCurrentMethod();
			throw new Exception(currentMethod.DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>  
	/// 设置程序开机启动（修改程序在注册表中的键值  ）
	/// </summary>  
	/// <param name="isAutoRun">true:开机启动,false:不开机自启</param> 
	/// <param name="applicationName">开机启动的程序名</param> 
	/// <param name="parentKey">注册表父级路径 （例：Registry.LocalMachine/Registry.CurrentUser）</param> 
	/// <param name="path">注册表子路径 （例：@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"）</param> 
	internal static void AutoRun(bool isAutoRun, string applicationName, RegistryKey parentKey, string path)
	{
		RegistryKey registryKey = parentKey.CreateSubKey(path);
		try
		{
			if (isAutoRun)
			{
				registryKey.SetValue(applicationName, Application.ExecutablePath);
			}
			else
			{
				registryKey.DeleteValue(applicationName, throwOnMissingValue: false);
			}
		}
		catch (Exception ex)
		{
			MethodBase currentMethod = MethodBase.GetCurrentMethod();
			throw new Exception(currentMethod.DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>  
	/// 设置程序开机启动（修改程序在注册表中的键值  ）
	/// </summary>  
	/// <param name="isAutoRun">true:开机启动,false:不开机自启</param> 
	/// <param name="applicationName">开机启动的程序名</param> 
	/// <param name="parentKey">注册表父级路径 （例：Registry.LocalMachine/Registry.CurrentUser）</param> 
	/// <param name="path">注册表子路径 （例：@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"）</param> 
	/// <param name="executablePath">应用程序的可执行文件的路径，包括可执行文件的名称</param> 
	internal static void AutoRun(bool isAutoRun, string applicationName, RegistryKey parentKey, string path, string executablePath)
	{
		RegistryKey registryKey = parentKey.CreateSubKey(path);
		try
		{
			if (isAutoRun)
			{
				registryKey.SetValue(applicationName, executablePath);
			}
			else
			{
				registryKey.DeleteValue(applicationName, throwOnMissingValue: false);
			}
		}
		catch (Exception ex)
		{
			MethodBase currentMethod = MethodBase.GetCurrentMethod();
			throw new Exception(currentMethod.DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>
	/// 获取进程专用内存(KB)
	/// </summary>
	/// <param name="processName">进程名，为空时表示当前进程</param>
	/// <returns>KB</returns>
	internal static long GetProcessMemory(string processName = "")
	{
		long result = 0L;
		Process process = null;
		try
		{
			if (string.IsNullOrEmpty(processName))
			{
				process = Process.GetCurrentProcess();
			}
			else
			{
				Process[] processesByName = Process.GetProcessesByName(processName);
				if (processesByName.Length == 0)
				{
					throw new Exception("未找到名为" + processName + "的进程");
				}
				if (processesByName.Length > 1)
				{
					throw new Exception($"根据名称{processName}找到{processesByName.Length}个进程");
				}
				process = processesByName[0];
			}
			PerformanceCounter performanceCounter = new PerformanceCounter("Process", "Working Set - Private", process.ProcessName);
			result = (long)(performanceCounter.NextValue() / 1024f);
		}
		catch
		{
			result = -1L;
		}
		finally
		{
			process?.Dispose();
		}
		return result;
	}

	/// <summary>
	///
	/// </summary>
	/// <param name="process"></param>
	/// <param name="minSize"></param>
	/// <param name="maxSize"></param>
	/// <returns></returns>
	[DllImport("kernel32.dll")]
	internal static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);

	/// <summary>  
	/// 释放内存  
	/// </summary>  
	internal static void ClearMemory()
	{
		GC.Collect();
		GC.WaitForPendingFinalizers();
		if (Environment.OSVersion.Platform == PlatformID.Win32NT)
		{
			SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
		}
	}
}
